package org.example;

import lombok.Data;
import sun.misc.Unsafe;

public class Main {
    //学习unsafe对象的获取以及cas相关方法
    public static void main2(String[] args) throws NoSuchFieldException {
        Unsafe unsafe = UnsafeAccessor.getUnsafe();
        Teacher t = new Teacher();

        //获取域的偏移地址
        long idOfferSet = unsafe.objectFieldOffset(Teacher.class.getDeclaredField("id"));
        long nameOfferSet = unsafe.objectFieldOffset(Teacher.class.getDeclaredField("name"));

        //执行cas操作
        unsafe.compareAndSwapInt(t, idOfferSet, 0, 1);
        unsafe.compareAndSwapObject(t, nameOfferSet, null, "张三");

        //验证结果
        System.out.println(t);
    }

    //使用unsafe对象模拟实现原子整数类AtomicInteger
    public static void main(String[] args) {
        Account.demo(new MyAtomicInteger(10000));
    }
}
class MyAtomicInteger implements Account{
    private volatile int value;
    private static final  Unsafe unsafe;

    private static final long valueOffset;

    static {
        unsafe =  UnsafeAccessor.getUnsafe();
        try {
            valueOffset = unsafe.objectFieldOffset(MyAtomicInteger.class.getDeclaredField("value"));
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    public MyAtomicInteger(int value) {
        this.value = value;
    }

    public int getValue(){
        return value;
    }
    public void decrement(int amount){
        while(true){
            int prev = value;
            int next = prev - amount;
            if (unsafe.compareAndSwapInt(this, valueOffset, prev, next)) {
                break;
            }
        }
    }

    @Override
    public Integer getBalance() {
        return value;
    }

    @Override
    public void withdraw(Integer amount) {
        decrement(amount);
    }
}
@Data
class Teacher{
    volatile int id;
    volatile String name;
}